﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

namespace Traceability.Register.Infrastructrue
{
    public class BaseRepository<TEntity> : IBaseRepository<TEntity> where TEntity : class
    {
        private readonly MyDBContext db;



        public BaseRepository(MyDBContext db)
        {
            this.db = db;
        }

        /// <summary>
        /// 查询
        /// </summary>
        /// <returns></returns>
        public async Task<IList<TEntity>> GetAllAsync()
        {
            return await db.Set<TEntity>().ToListAsync();
        }

        /// <summary>
        /// 同步方法
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual TEntity Insert(TEntity entity)
        {
            db.Set<TEntity>().Add(entity);
            db.SaveChanges();
            return entity;
        }

        /// <summary>
        /// 异步方法
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual async Task<TEntity> InsertAsync(TEntity entity)
        {
            await db.Set<TEntity>().AddAsync(entity);
            await db.SaveChangesAsync();
            return entity;
        }

        /// <summary>
        /// 根据实体集合批删
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public virtual async Task<int> DeleteMany(List<TEntity> entities)
        {
            db.Set<TEntity>().RemoveRange(entities);
            return await db.SaveChangesAsync();
        }

        /// <summary>
        /// 根据实体集合批删
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public virtual async Task<int> DeleteMany(params int[] idList)
        {
            int i = 0;
            foreach (var item in idList)
            {
                var entity = await db.Set<TEntity>().FindAsync(item);
                if (entity != null)
                {
                    db.Set<TEntity>().Remove(entity);
                    await db.SaveChangesAsync();
                    i++;
                }
            }

            return i;
        }

        /// <summary>
        /// 根据条件查第一条
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual async Task<TEntity> QueryFirstAsync(Expression<Func<TEntity, bool>> predicate)
        {
            return await db.Set<TEntity>().FirstOrDefaultAsync(predicate);
        }

        /// <summary>
        /// 根据条件查多条
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual async Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> predicate)
        {
            return await db.Set<TEntity>().Where(predicate).ToListAsync();
        }


        /// <summary>
        /// 根据条件查多条
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual async Task<List<TEntity>> QueryAsync<TKey>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> orderby, bool Desc = false)
            where TKey : struct
        {
            if (Desc)
            {
                return await db.Set<TEntity>().Where(predicate).OrderBy(orderby).ToListAsync();
            }
            else
            {
                return await db.Set<TEntity>().Where(predicate).OrderByDescending(orderby).ToListAsync();
            }
        }

        /// <summary>
        /// 根据条件是否存在
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual async Task<bool> ExistsAsync(Expression<Func<TEntity, bool>> predicate)
        {
            return await db.Set<TEntity>().AnyAsync(predicate);
        }

        /// <summary>
        /// 根据条件是否存在--延迟查询
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual IQueryable Queryable(Expression<Func<TEntity, bool>> predicate)
        {
            return db.Set<TEntity>().Where(predicate);
        }

        /// <summary>
        /// 根据条件是否存在--延迟查询
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual IQueryable Queryable()
        {
            return db.Set<TEntity>().AsQueryable();
        }


        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public Task<int> UpdateAsync(TEntity entity)
        {
            db.Set<TEntity>().Update(entity);
            return db.SaveChangesAsync();
        }
    }
}
